/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.namabank.db;

import org.apache.log4j.Logger;
import org.hibernate.Transaction;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.StatelessSession;
import org.hibernate.cfg.*;

/**
 *
 * @author Nam A
 */
public class GlobalHibernate {

    private static SessionFactory sessionFactory = null;
    private static Configuration config = null;
    static Logger logger = Logger.getLogger(GlobalHibernate.class);
    private static ThreadLocal<Session> sessionLocal = new ThreadLocal<Session>();
    private static ThreadLocal<StatelessSession> statelessSessionLocal = new ThreadLocal<StatelessSession>();

    static synchronized void initConfig() {
        if (config == null) {
            config = new Configuration().configure();
        }
    }

    public static synchronized void initSessionFactory() {
        if (sessionFactory == null) {
            initConfig();
            sessionFactory = config.buildSessionFactory();
        }
    }

    public static SessionFactory getSessionFactory() {
        initSessionFactory();
        return sessionFactory;
    }

    public static synchronized Session openSession() {
        initSessionFactory();
        if (sessionLocal.get() == null) {
            sessionLocal.set(getSessionFactory().openSession());
        }
        Session session = sessionLocal.get();
        session.beginTransaction();
        return session;
    }

    public static synchronized StatelessSession openStatelessSession() {
        initSessionFactory();
        if (statelessSessionLocal.get() == null) {
            statelessSessionLocal.set(sessionFactory.openStatelessSession());
        }
        StatelessSession stsess = statelessSessionLocal.get();
        stsess.beginTransaction();
        return stsess;
    }

    public static synchronized boolean closeStatelessSession(boolean submit) {
        try {
            StatelessSession session = statelessSessionLocal.get();
            if (session == null) {
                return true;
            }
            Transaction trans = session.getTransaction();
            if (trans != null && trans.isActive()) {
                if (submit) {
                    trans.commit();
                } else {
                    trans.rollback();
                }
            }
            session.close();
            statelessSessionLocal.set(null);
        } catch (Exception ex) {
            logger.error("Loi khi dong StatelessSession", ex);
            statelessSessionLocal.set(null);
            return false;
        }
        return true;
    }

    public static synchronized boolean closeSession(boolean submit) {
        try {
            Session session = sessionLocal.get();
            if (session == null) {
                return true;
            }
            Transaction trans = session.getTransaction();
            if (trans != null && trans.isActive()) {
                if (submit) {
                    trans.commit();
                } else {
                    session.clear();
                    trans.rollback();
                }
            }
            session.close();
            sessionLocal.set(null);
        } catch (Exception ex) {
            logger.error("Loi khi dong session", ex);
            sessionLocal.set(null);
            return false;
        }
        return true;
    }

    public static synchronized void closeFactory() {
        if (sessionFactory != null) {
            sessionFactory.close();
            sessionFactory = null;
        }
    }

    public static synchronized boolean closeAllSession(boolean submit) {
        boolean res = closeSession(submit);
        if (res) {
            return closeStatelessSession(submit);
        }
        return res;
    }

    public static String getProperty(String s) {
        if (config == null) {
            initConfig();
        }
        if (config != null) {
            return config.getProperty(s);
        }
        return null;
    }

    public static InterfaceDBUtil getDbUtil() {
        String dialect = getProperty("dialect");
        if (dialect != null) {
            if (dialect.endsWith("FirebirdDialect")) {
                return new FirebirdDBUtil();
            }
        }
        return new OracleDBUtil();
    }

    public static String getDbName() {
        String dialect = getProperty("dialect");
        if (dialect != null) {
            if (dialect.contains("Firebird")) {
                return "FIREBIRD";
            }
            if (dialect.contains("Oracle")) {
                return "ORACLE";
            }
        }
        return null;
    }
}
